<html>
<head><meta charset="utf-8"><title>add qualified function assist · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html">add qualified function assist</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="194351945"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194351945" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194351945">(Apr 16 2020 at 19:00)</a>:</h4>
<p>I'm starting work on the next feature of the <code>add_function</code> assist: generating the function in another module if a qualified path is used! (inspired by <a href="https://github.com/rust-analyzer/rust-analyzer/pull/3969#issuecomment-613910383" title="https://github.com/rust-analyzer/rust-analyzer/pull/3969#issuecomment-613910383">matklad's feature request</a>)<br>
And I'm obviously getting stuck.</p>
<p>I assume I want to find the target module via <code>code_model::Module::find_use_path</code>? <br>
It would be nice to pass a <code>ModuleDefId::FunctionId</code> for the <code>item</code> argument, only the given function doesn't exist yet.<br>
I could probably remove the last segment from the path and try to pass that to <code>find_use_path</code> (as a <code>ModuleDefId::ModuleId</code>), does that sound reasonable?<br>
If yes, do you also have some tips on how to do that path manipulation?</p>



<a name="194352228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194352228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194352228">(Apr 16 2020 at 19:02)</a>:</h4>
<p>No, <code>find_use_path</code> is a reverse operation, you want <code>Semantic::resolve_path</code></p>



<a name="194352288"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194352288" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194352288">(Apr 16 2020 at 19:02)</a>:</h4>
<p>ah. thanks!</p>



<a name="194352386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194352386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194352386">(Apr 16 2020 at 19:03)</a>:</h4>
<p>will that resolve a path to <code>foo::bar</code>, if the module <code>foo</code> exists but the function <code>bar</code> doesn't?</p>



<a name="194352848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194352848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194352848">(Apr 16 2020 at 19:07)</a>:</h4>
<p>nope.<br>
again, do i want to try to resolve <code>foo</code> in that example to find the module? and then generate <code>fn bar ...</code> in there?</p>



<a name="194353333"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194353333" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194353333">(Apr 16 2020 at 19:11)</a>:</h4>
<p>You'll need to get only the <code>foo</code> path</p>



<a name="194353396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194353396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194353396">(Apr 16 2020 at 19:11)</a>:</h4>
<p><code>ast::Path::qualifier</code> will give you a parent path</p>



<a name="194354110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194354110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194354110">(Apr 16 2020 at 19:17)</a>:</h4>
<p>oh. i'm already using <code>path.qualifier().is_some()</code> to purposefully disable the assist <span aria-label="face palm" class="emoji emoji-1f926" role="img" title="face palm">:face_palm:</span><br>
looks like i can make some progress, thanks for the support!</p>



<a name="194480547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194480547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194480547">(Apr 17 2020 at 18:18)</a>:</h4>
<p>so generating the function in another module in the same file works: <a href="https://github.com/rust-analyzer/rust-analyzer/pull/3998" title="https://github.com/rust-analyzer/rust-analyzer/pull/3998">https://github.com/rust-analyzer/rust-analyzer/pull/3998</a><br>
but generating it in another file doesn't, it inserts it in the original file with the offset calculated from the other file...<br>
does that require changes in the whole assist infrastructure?</p>



<a name="194484326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194484326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194484326">(Apr 17 2020 at 18:50)</a>:</h4>
<p>alright, i see that in <code>ra_ide::assists::assists</code>, the <code>AssistAction</code> in <code>ResolvedAssist.action</code> that doesn't contain any file information is turned into a <code>SourceChange</code> which <em>does</em> contain a <code>FileId</code> (for each <code>SourceFileEdit</code>).<br>
I think I might add a new field to <code>ra_assists::AssistAction</code>, something like <code>enum AssistTargetFile {CurrentFile, TargetFile(FileId)}</code></p>



<a name="194564588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194564588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194564588">(Apr 18 2020 at 21:31)</a>:</h4>
<p>alright, that worked, functions can be added to other files now. what's missing is the assist navigating to the changed file though...<br>
the file shows up in the <code>codeAction</code> response in <code>command.arguments.0.cursorPosition.textDocument</code>,  so is that functionality missing in the lsp clients?</p>
<p>right now, the response looks like this:</p>
<div class="codehilite"><pre><span></span>{
        &quot;command&quot;: {
            &quot;arguments&quot;: [
                {
                    &quot;cursorPosition&quot;: {
                        &quot;position&quot;: {
                            &quot;character&quot;: 4,
                            &quot;line&quot;: 8
                        },
                        &quot;textDocument&quot;: {
                            &quot;uri&quot;: &quot;file:///tmp/bla/src/main.rs&quot;
                        }
                    },
                    &quot;label&quot;: &quot;Add function&quot;,
                    &quot;workspaceEdit&quot;: {
                        &quot;documentChanges&quot;: [
                            {
                                &quot;edits&quot;: [
                                    {
                                        &quot;newText&quot;: &quot;\n\nfn bar() {\n    todo!()\n}&quot;,
                                        &quot;range&quot;: {
                                            &quot;end&quot;: {
                                                &quot;character&quot;: 1,
                                                &quot;line&quot;: 5
                                            },
                                            &quot;start&quot;: {
                                                &quot;character&quot;: 1,
                                                &quot;line&quot;: 5
                                            }
                                        }
                                    }
                                ],
                                &quot;textDocument&quot;: {
                                    &quot;uri&quot;: &quot;file:///tmp/bla/src/main.rs&quot;,
                                    &quot;version&quot;: null
                                }
                            }
                        ]
                    }
                }
            ],
            &quot;command&quot;: &quot;rust-analyzer.applySourceChange&quot;,
            &quot;title&quot;: &quot;Add function&quot;
        },
        &quot;title&quot;: &quot;Add function&quot;
    }
</pre></div>



<a name="194565619"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194565619" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194565619">(Apr 18 2020 at 21:56)</a>:</h4>
<blockquote>
<p>that functionality missing in the lsp clients?</p>
</blockquote>
<p>Which client do you use? It works with VS Code (the "add module" extension makes use of it)</p>



<a name="194565877"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194565877" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194565877">(Apr 18 2020 at 22:03)</a>:</h4>
<p>Hmm then I'm missing something, it doesn't work for me with nvim(coc-rust-analyzer) and with vs code. Gonna take another look tomorrow :)</p>



<a name="194565928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194565928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194565928">(Apr 18 2020 at 22:04)</a>:</h4>
<p>A good way to check would be to apply the fixit for <code>mod some_non_existent_module;</code> It should move you to the new file</p>



<a name="194566486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194566486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194566486">(Apr 18 2020 at 22:19)</a>:</h4>
<p>Upstream issue: <a href="https://github.com/microsoft/language-server-protocol/issues/724" title="https://github.com/microsoft/language-server-protocol/issues/724">https://github.com/microsoft/language-server-protocol/issues/724</a></p>



<a name="194587725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194587725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194587725">(Apr 19 2020 at 09:16)</a>:</h4>
<p>Hmm... the <code>codeAction</code> response for the "add module" assist looks like this:</p>
<div class="codehilite"><pre><span></span>{
        &quot;command&quot;: {
            &quot;arguments&quot;: [
                {
                    &quot;cursorPosition&quot;: null,
                    &quot;label&quot;: &quot;create module&quot;,
                    &quot;workspaceEdit&quot;: {
                        &quot;documentChanges&quot;: [
                            {
                                &quot;kind&quot;: &quot;create&quot;,
                                &quot;uri&quot;: &quot;file:///tmp/bla/src/foo.rs&quot;
                            }
                        ]
                    }
                }
            ],
            &quot;command&quot;: &quot;rust-analyzer.applySourceChange&quot;,
            &quot;title&quot;: &quot;create module&quot;
        },
        &quot;title&quot;: &quot;create module&quot;
    }
</pre></div>


<p>I don't think I can use this for <code>add_function</code> :/</p>



<a name="194599735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194599735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194599735">(Apr 19 2020 at 14:15)</a>:</h4>
<p>the plot thickens!<br>
<code>cursorPosition.textDocument.uri</code> is read <a href="https://github.com/rust-analyzer/rust-analyzer/blob/36840bd6c71eaf18cdf418c92af51c24e547a4a7/editors/code/src/source_change.ts#L40" title="https://github.com/rust-analyzer/rust-analyzer/blob/36840bd6c71eaf18cdf418c92af51c24e547a4a7/editors/code/src/source_change.ts#L40">here</a>, but if it differs from the currently opened URI(?), the function exits early<br>
i guess this needs to be changed as well?</p>



<a name="194708624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/add%20qualified%20function%20assist/near/194708624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Timo Freiberg <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/add.20qualified.20function.20assist.html#194708624">(Apr 20 2020 at 17:37)</a>:</h4>
<p>Alright, the only thing really missing is having unit tests for generating the function in another file. Unfortunately, <a href="https://github.com/rust-analyzer/rust-analyzer/blob/2e0b7b0159ed922693db48f3f94ed95b1827494a/crates/ra_assists/src/lib.rs#L229" title="https://github.com/rust-analyzer/rust-analyzer/blob/2e0b7b0159ed922693db48f3f94ed95b1827494a/crates/ra_assists/src/lib.rs#L229">the assist helper </a> always applies the assist to the starting file and only compares the <code>expected</code> with that file.<br>
I guess I see where changes need to be made... This has proven to be more complex than I thought!</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>